package for_all;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Hashtable;


public class Room implements Serializable {

    
    // -------------------------------------------------------------------------
    // Variablendeklarationen
    private String roomName;
    private Hashtable<String,User> users;
    private ArrayList<String> userNames;
    
    //Nachrichtenklassen
    private newUserInRoom newUserInRoomAttribut;
    private userLeavedRoom userLeavedRoomAttribut;
    private roomNameChanged roomNameChangedAttribut;
    private roomDeleted roomDeletedAttribut;
    private roomCreated roomCreatedAttribut;
    
    private userJoinsRoom userJoinsRoomAttribut;
    private getRoomNames getRoomNamesAttribut;
    
    
    // -------------------------------------------------------------------------
    // Konstruktor
    public Room (String roomName) {
        
        this.roomName = roomName;
        this.users = new Hashtable<>();
        this.userNames = new ArrayList<>();
        
        this.newUserInRoomAttribut = null;
        this.userLeavedRoomAttribut = null;
        this.roomNameChangedAttribut = null;
        this.roomDeletedAttribut = null;
        this.roomCreatedAttribut = null;
        
        this.userJoinsRoomAttribut = null;
        this.getRoomNamesAttribut = null;
    }
    
    
    // -------------------------------------------------------------------------
    // Nutzer hinzufügen
    public void addUser(User user) {
        for(String temp: this.userNames) { //andere User benachrichtigen
            this.users.get(temp).getClientHandler().informUserAboutNewUserInRoom(user.getUserName());
        }
        
        this.users.put(user.getUserName(), user);
        this.userNames.add(user.getUserName());
    }
    
    
    // -------------------------------------------------------------------------
    // Nutzer entfernen
    public void removeUser(User user) {
        this.users.remove(user.getUserName());
        this.userNames.remove(user.getUserName());
        
        for(String temp: this.userNames) { //andere User benachrichtigen
            this.users.get(temp).getClientHandler().informUserAboutUserLeaved(user.getUserName());
        }
    }
    
    
    // -------------------------------------------------------------------------
    // Anzahl der Nutzer im Raum
    public int getNumberOfUsers() {
        return this.users.size();
    }
    
    
    // -------------------------------------------------------------------------
    // Namen aller User
    public ArrayList<String> getUserNames() {
        return this.userNames;
    }
    
    
    // -------------------------------------------------------------------------
    // Raumnamen ändern
    public void changeRoomName(String newName) {
        //informUsersAboutRoomNameChanged(newName);
        this.roomName = newName;
    }
    
    
    // -------------------------------------------------------------------------
    // Name des Raumes
    public String getRoomName() {
        return this.roomName;
    }
    
    
    // -------------------------------------------------------------------------
    // sendet eine Nachricht an alle User im Raum
    public void sendMessageToAllUSers(Message msg) {
        for(String user:this.userNames) {
            this.users.get(user).getClientHandler().sendMessageToClient(msg);
        }
    }
    
    
    // -------------------------------------------------------------------------
    // sendet eine Nachricht an alle User im Raum, mit Ausnahme von User without
    // Nützlich, falls ein User Nachrichten an die anderen im Raum schreibt
    public void sendMessageToAllUSersWithout(Message msg, String without) {
        for(String user:this.userNames) {
            if(user.compareTo(without) != 0) {
                this.users.get(user).getClientHandler().sendMessageToClient(msg);
            }
        }
    }
    
    
    // -------------------------------------------------------------------------
    // Getter und Setter Methoden für die Nachrichtenklassen
    public newUserInRoom getNewUserInRoom() {
        return this.newUserInRoomAttribut;
    }
    
    
    public void setNewUserInRoom(String name) {
        this.newUserInRoomAttribut = new newUserInRoom(name);
    }
    
    
    public void setNewUserInRoom(newUserInRoom object) {
        this.newUserInRoomAttribut = object;
    }
    
    
    public userLeavedRoom getUserLeavedRoom() {
        return this.userLeavedRoomAttribut;
    }
    
    
    public void setUserLeavedRoom(String name) {
        this.userLeavedRoomAttribut = new userLeavedRoom(name); 
    }
    
    
    public void setUserLeavedRoom(userLeavedRoom object) {
        this.userLeavedRoomAttribut = object; 
    }
    
    
    public roomNameChanged getRoomNameChanged() {
        return this.roomNameChangedAttribut;
    }
    
    
    public void setRoomNameChanged(String oldName, String newName) {
        this.roomNameChangedAttribut = new roomNameChanged(oldName, newName);
    }
    
    
    public void setRoomNameChanged(roomNameChanged object) {
        this.roomNameChangedAttribut = object;
    }
    
    
    public roomDeleted getRoomDeleted() {
        return this.roomDeletedAttribut;
    }
    
    
    public void setRoomDeleted(String name) {
        this.roomDeletedAttribut = new roomDeleted(name);
    }
    
    
    public void setRoomDeleted(roomDeleted object) {
        this.roomDeletedAttribut = object;
    }
    
    
    public roomCreated getRoomCreated() {
        return roomCreatedAttribut;
    }
    
    
    public void setRoomCreated(String name) {
        roomCreatedAttribut = new roomCreated(name);
    }
    
    
    public void setRoomCreated(roomCreated object) {
        roomCreatedAttribut = object;
    }
    
    
    public userJoinsRoom getuserJoinsRoom() {
        return userJoinsRoomAttribut;
    }
    
    
    public void setUserJoinsRoom(String roomName, String userName) {
        userJoinsRoomAttribut = new userJoinsRoom(roomName, userName);
    }
    
    
    public void setUserJoinsRoom(userJoinsRoom object) {
        userJoinsRoomAttribut = object;
    }
    
    
    public void setGetRoomNames(String userName) {
        getRoomNamesAttribut = new getRoomNames(userName);
    }
    
    
    public void setGetRoomNames(getRoomNames object) {
        getRoomNamesAttribut = object;
    }
    
    
    public getRoomNames getGetRoomNames() {
        return getRoomNamesAttribut;
    }
   
    
    /////////////////////////////////////////////////////////////////
    //Ab hier Klassen die vom Server an den Client gesendet werden
    ////////////////////////////////////////////////////////////////
        
    // -------------------------------------------------------------------------
    // Wird an Client gesendet, wenn ein neuer User den Raum betritt
    public class newUserInRoom implements Serializable {
        private String Name;

        public newUserInRoom(String userName) {
            this.Name = userName;
        }
        
        public String getName() {
            return Name;
        }
    }
    
    
    // -------------------------------------------------------------------------
    // Wird an Client gesendet, wenn ein User den Raum verlassen hat
    public class userLeavedRoom implements Serializable {
        private String Name;
        
        public userLeavedRoom(String userName) {
            this.Name = userName;
        }
        
        public String getName() {
            return Name;
        }
    }
    
    
    // -------------------------------------------------------------------------
    // Wird an Client gesendet, wenn der Raumname geändert wurde
    public class roomNameChanged implements Serializable {
        private String oldName;
        private String newName;

        public roomNameChanged(String oldName, String newName) {
            this.oldName = oldName;
            this.newName = newName;
        }
        
        public String getOldName() {
            return oldName;
        }
        
        public String getNewName() {
            return newName;
        }
    }
    
    
    // -------------------------------------------------------------------------
    // Wird an Client gesendet, wenn der Raum gelöscht wurde
    public class roomDeleted implements Serializable {
        private String roomName;

        public roomDeleted(String roomName) {
            this.roomName = roomName;
        }
        
        public String getRoomName() {
            return roomName;
        }
    }
    
    
    // -------------------------------------------------------------------------
    // Wird an Client gesendet, wenn ein neuer Raum angelegt wurde wurde
    public class roomCreated implements Serializable {
        private String roomName;

        public roomCreated(String roomName) {
            this.roomName = roomName;
        }
        
        public String getRoomName() {
            return roomName;
        }
    }
    
    
    
    /////////////////////////////////////////////////////////////////
    //Ab hier Klassen die vom Client an den Server gesendet werden
    ////////////////////////////////////////////////////////////////
    
    // -------------------------------------------------------------------------
    // Wird an Server gesendet, wenn Client Raum beitreten will
    public class userJoinsRoom implements Serializable {
        private String roomName;
        private String userName;
        
        public userJoinsRoom(String roomName, String userName) {
            this.roomName = roomName;
            this.userName = userName;
        }
        
        public String getUserName() {
            return userName;
        }
        
        public String getRoomName() {
            return roomName;
        } 
    }
    
    
    // -------------------------------------------------------------------------
    // Wird an Server gesendet, wenn der Client eine Liste aller Raumnamen haben will
    public class getRoomNames implements Serializable {
        private String userName;
        
        public getRoomNames(String userName) {
            this.userName = userName;
        }
        
        public String getUserName() {
            return userName;
        }
    }
    
    
    // -------------------------------------------------------------------------
    // wird gesendet wenn ein User einem Raum beitritt (dann ändert sich sein raum ja)
    static public class UserChangedRoom implements Serializable {
        private String userName;
        private String newRoomName;
        
        public UserChangedRoom(String userName, String newRoomName) {
            this.userName = userName;
            this.newRoomName = newRoomName;
        }
        
        public String getUserName() {
            return userName;
        }
        
        public String getRoomName() {
            return newRoomName;
        }
    }
    
}